# -*- coding: utf-8 -*-

#
# peerscape.http.controllers.postif
#
# Copyright 2008 Helsinki Institute for Information Technology
# and the authors.
#
# Authors:
#       Konrad Markus <konrad.markus@hiit.fi>
#

# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from __future__ import with_statement

import logging
import cgi
import urllib
import re
import uuid
from webob import Response
from webob.exc import HTTPForbidden, HTTPBadRequest, HTTPOk
from peerscape.http.controllers import BaseController

class Postif(BaseController):
    """Only post the value if key does not exist"""
    def index(self, req):
        if req.method == 'POST':
            db = req.environ['peerscape.db']
            iid = req.urlvars.get('peerscape.hexlabel')
            path = urllib.unquote(req.urlvars.get('peerscape.path'))

            if not iid or not path:
                return HTTPBadRequest()

            path = '/'+path
            if path.find('$uiid'):
                # substitute $uiid in the path with a generated uiid
                u = uuid.uuid4()
                p = re.compile('\$uuid')
                path = p.sub(str(u), path)

            dom_cipher = None
            if req.POST.get('auto_crypt'):
                try:
                    dom_cipher = db.get_group_cipher(iid)
                except LookupError:
                    assert dom_cipher == None
                    pass

            # write value if path does not exist
            if not db.get(iid, path):
                if req.POST.has_key('value'):
                    try:
                        if req.headers.get('content-type') and req.headers['content-type'].startswith('multipart/form-data'):
                            # file upload
                            upload = req.POST['value']
                            if upload.__class__ == cgi.FieldStorage:
                                with upload.file as f:
                                    value = f.read()

                            # if a file upload substitute $ext in the path with the original file extension of the uploaded file
                            if path.find('\$ext'):
                                head, ext = os.path.splitext(upload.filename)
                                if ext:
                                    if ext.startswith('.'):
                                        ext = ext[1:]

                                    p = re.compile('\$ext')
                                    path = p.sub(str(ext), path)

                                if req.POST.has_key('escape_html'):
                                    value = cgi.escape(value)

                                db.put(iid, path, value, cipher=dom_cipher)
                        else:
                            value = req.POST['value']
                            if req.POST.has_key('escape_html'):
                                value = cgi.escape(value)

                            db.put(iid, path, value, cipher=dom_cipher)
                    except:
                        logging.exception('postif: error.')
                        return HTTPForbidden()
                else:
                    return HTTPBadRequest()

            # success response, even if nothing written
            res = HTTPOk()
            if req.POST.has_key('jsonp'):
                body = '%s("%s")' % (req.POST['jsonp'], path)
                if isinstance(body, unicode):
                    res.unicode_body = body
                else:
                    res.body = body
            else:
                body = '("%s")' % path
                if isinstance(body, unicode):
                    res.unicode_body = body
                else:
                    res.body = body

            return res
        else:
            return HTTPBadRequest()
            
